package com.gang.mars.basic.parseannotation;

import java.lang.annotation.Annotation;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;

/**
 * @Author：gang.chen
 * @Date：2023/5/6 12:54
 */
final class GAnnotationTypeMappings {

    List<GAnnotationTypeMapping> mappings;

    public GAnnotationTypeMappings(Class<? extends Annotation> annotation)
    {
        this.mappings = new ArrayList<>();

        addAllMapping(annotation);
    }

    private void addAllMapping(Class<? extends Annotation> annotation)
    {
        Deque<GAnnotationTypeMapping> queue = new ArrayDeque<>();
        /**
         * 对主程序注解进行解析：GSpringBootApplication
         * */
        addIfPossible(queue, annotation);

        while (!queue.isEmpty())
        {
            GAnnotationTypeMapping mapping = queue.removeFirst();
            /**
             * 第一次：mapping = GSpringBootApplication
             * */
            this.mappings.add(mapping);

            addMetaAnnotationToQueue(queue, mapping);
        }
    }

    private void addIfPossible(Deque<GAnnotationTypeMapping> queue, Class<? extends Annotation> annotation)
    {
        queue.addLast(new GAnnotationTypeMapping(annotation));
    }

    private void addMetaAnnotationToQueue(Deque<GAnnotationTypeMapping> queue, GAnnotationTypeMapping mapping)
    {
        /**
         * 获取Mapping中的注解对象：GSpringBootApplication
         * 再从该注解对象中获取：所有注解对象
         * */
        Class<? extends Annotation> annotationMata = mapping.getAnnotation();

        Annotation[] declaredAnnotations = GAnnotationsScanner.getDeclaredAnnotations(annotationMata);

        for (Annotation annotation : declaredAnnotations) {

            addIfPossible(queue, annotation.annotationType());

        }
    }
}
